产品集成资源文档定价
立即开始

© 2026 CapSolver. All rights reserved.

联系我们

Slack: lola@capsolver.com

产品

  • reCAPTCHA v2
  • reCAPTCHA v3
  • Cloudflare Turnstile
  • Cloudflare Challenge
  • AWS WAF
  • 浏览器插件
  • 更多验证码类型

集成

  • Selenium
  • Playwright
  • Puppeteer
  • n8n
  • 合作伙伴
  • 查看所有集成

资源

  • 推荐返佣系统
  • 官方文档
  • API 参考
  • 博客
  • 常见问题 (FAQ)
  • 术语表
  • 系统状态

法律声明

  • 服务条款
  • 隐私政策
  • 退款政策
  • 请勿出售我的信息
博客/aws waf/如何使用NodeJS解决AWS验证码
Dec01, 2023

如何使用NodeJS解决AWS验证码

Ethan Collins

Ethan Collins

Pattern Recognition Specialist

在现代的网络环境中,保护在线资源免受自动化威胁至关重要。AWS Web Application Firewall (WAF) 是一个强大的安全层,通常会部署挑战或托管验证码来过滤恶意机器人。虽然对安全有效,但这些机制对合法的自动化任务(如网页爬取、监控或测试)构成了重大障碍。

本全面指南使用 Node.js 和 CapSolver 服务提供了一个强大的自动化解决方案。我们将逐步介绍如何设置环境、实现模块化的 Node.js 脚本,并利用 CapSolver 的专用 AntiAwsWafTask 来绕过 WAF 挑战(HTTP 202)和 WAF 验证码(HTTP 405)场景。在本教程结束时,您将拥有一个可直接投入生产的脚本,能够获取访问受保护内容所需的 aws-waf-token cookie。

⚙️ 前提条件

在开始之前,请确保准备好以下环境和信息:

  1. Node.js 环境:您的系统上已安装 Node.js(推荐使用 LTS 版本)。
  2. CapSolver API 密钥:您需要一个 CapSolver 账户和您的 API 密钥。
    • 获取您的 CapSolver API 密钥
  3. 代理(可选):如果目标网站有地理限制或您需要隐藏真实 IP,请准备一个 HTTP/HTTPS 代理。

🛠️ 第一步:安装必要的依赖

在您的项目目录中,执行以下命令以安装所需的 Node.js 模块:

bash Copy
npm install axios cheerio
  • axios:用于发送 HTTP 请求。
  • cheerio:用于解析 HTML 内容并提取 AWS WAF 挑战所需的参数。

💻 第二步:Node.js 核心代码实现

以下是用于解决 AWS WAF 挑战和验证码的 Node.js 脚本。它会自动检测网站返回的状态码,并根据需要执行相应的 CapSolver 任务。

请将以下代码保存为 aws_waf_solver.js。

javascript Copy
const axios = require('axios');
const cheerio = require('cheerio');
const { URL } = require('url');

// ⚠️ 配置:请替换为您的实际值
const CLIENT_KEY = "YOUR_CAPSOLVER_API_KEY"; // 替换为您的 CapSolver API 密钥
const PAGE_URL = "https://norway-meetup.aws.wslab.no/"; // 替换为目标网站 URL
const PROXY = "YOUR_PROXY_ADDRESS"; // 替换为您的代理地址(格式:user:pass@ip:port 或 ip:port)

// --- 辅助函数 ---

/**
 * 暂停执行指定的毫秒数
 * @param {number} ms 毫秒数
 */
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * 创建 CapSolver 任务
 * @param {object} payload 任务负载
 * @returns {Promise<object>} 任务创建结果
 */
async function createTask(payload) {
    try {
        const res = await axios.post('https://api.capsolver.com/createTask', {
            clientKey: CLIENT_KEY,
            task: payload
        });
        if (res.data.errorId !== 0) {
            throw new Error(`CapSolver API 错误: ${res.data.errorDescription}`);
        }
        return res.data;
    } catch (error) {
        console.error("创建 CapSolver 任务失败:", error.message);
        return null;
    }
}

/**
 * 获取 CapSolver 任务结果,直到任务完成
 * @param {string} taskId 任务 ID
 * @returns {Promise<object>} 任务结果
 */
async function getTaskResult(taskId) {
    if (!taskId) return null;
    console.log(`等待任务结果(ID: ${taskId})...`);
    try {
        let success = false;
        let result = null;
        while (!success) {
            await sleep(3000); // 每 3 秒查询一次
            const res = await axios.post('https://api.capsolver.com/getTaskResult', {
                clientKey: CLIENT_KEY,
                taskId: taskId
            });

            if (res.data.errorId !== 0) {
                throw new Error(`CapSolver API 错误: ${res.data.errorDescription}`);
            }

            if (res.data.status === "ready") {
                success = true;
                result = res.data;
                console.log("任务完成,已获得解决方案。");
            } else if (res.data.status === "processing") {
                console.log("任务仍在处理中...");
            }
        }
        return result;
    } catch (error) {
        console.error("获取 CapSolver 任务结果失败:", error.message);
        return null;
    }
}

// --- 核心求解函数 ---

/**
 * 解决 AWS WAF 挑战(状态码 202)
 * @param {string} awsChallengeJS AWS 挑战 JavaScript URL
 * @returns {Promise<string|null>} 解决后的 AWS WAF Cookie 值
 */
async function solveAwsChallenge(awsChallengeJS) {
    console.log("检测到 AWS WAF 挑战(状态码 202),开始求解...");
    const taskPayload = {
        type: "AntiAwsWafTask",
        websiteURL: PAGE_URL,
        awsChallengeJS,
        proxy: PROXY
    };
    const taskData = await createTask(taskPayload);
    if (!taskData) return null;

    const result = await getTaskResult(taskData.taskId);
    if (result && result.solution && result.solution.cookie) {
        return result.solution.cookie;
    }
    return null;
}

/**
 * 解决 AWS WAF 验证码 + 挑战(状态码 405)
 * @param {string} htmlContent 包含验证码参数的 HTML 内容
 * @param {string} awsChallengeJS AWS 挑战 JavaScript URL
 * @returns {Promise<string|null>} 解决后的 AWS WAF Cookie 值
 */
async function solveAwsCaptchaChallenge(htmlContent, awsChallengeJS) {
    console.log("检测到 AWS WAF 验证码(状态码 405),开始求解...");
    const $ = cheerio.load(htmlContent);
    const scriptContent = $("script[type='text/javascript']").last().html();

    if (!scriptContent) {
        console.error("无法找到包含验证码参数的脚本内容。");
        return null;
    }

    // 使用正则表达式提取关键参数
    const keyMatch = /"key":"(.*?)"/.exec(scriptContent);
    const ivMatch = /"iv":"(.*?)"/.exec(scriptContent);
    const contextMatch = /"context":"(.*?)"/.exec(scriptContent);

    const key = keyMatch ? keyMatch[1] : null;
    const iv = ivMatch ? ivMatch[1] : null;
    const context = contextMatch ? contextMatch[1] : null;

    if (!key || !iv || !context) {
        console.error("从脚本中未能提取所有必需的验证码参数(key, iv, context)。");
        return null;
    }

    console.log(`提取的参数: Key=${key}, IV=${iv}, Context=${context}`);

    const taskPayload = {
        type: "AntiAwsWafTask", // CapSolver 统一使用此任务类型
        websiteURL: PAGE_URL,
        awsKey: key,
        awsIv: iv,
        awsContext: context,
        awsChallengeJS,
        proxy: PROXY
    };

    const taskData = await createTask(taskPayload);
    if (!taskData) return null;

    const result = await getTaskResult(taskData.taskId);
    if (result && result.solution && result.solution.cookie) {
        return result.solution.cookie;
    }
    return null;
}

/**
 * 主执行函数
 */
async function main() {
    let awsWafCookie = null;
    let initialResponse = null;

    // 1. 初始请求目标页面
    try {
        console.log(`请求目标页面: ${PAGE_URL}`);
        initialResponse = await axios.get(PAGE_URL, {
            headers: {
                // 模拟浏览器请求头
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                "Accept-Encoding": "gzip, deflate, br",
                "Accept-Language": "en-US,en;q=0.9",
                "Cache-Control": "max-age=0",
                "Upgrade-Insecure-Requests": "1"
            },
            // 允许处理 2xx、3xx、4xx 状态码
            validateStatus: (status) => status >= 200 && status < 500
        });
        console.log(`初始响应状态码: ${initialResponse.status}`);
    } catch (error) {
        console.error(`初始请求失败: ${error.message}`);
        return;
    }

    const $ = cheerio.load(initialResponse.data);
    const scriptTags = $('script[src*="token.awswaf.com"]');
    const awsChallengeJS = scriptTags.attr('src');

    if (!awsChallengeJS) {
        console.log("未检测到 AWS WAF 挑战脚本。该网站可能未受保护或已通过验证。");
        // 如果没有挑战脚本,直接使用初始响应
        if (initialResponse.status === 200) {
            console.log("网站加载成功。");
            // console.log(initialResponse.data); // 打印最终内容
            return;
        }
    } else {
        console.log(`检测到 AWS WAF 挑战脚本 URL: ${awsChallengeJS}`);
    }


    // 2. 根据状态码确定并解决挑战/验证码
    if (initialResponse.status === 202) {
        // 仅 AWS WAF 挑战
        awsWafCookie = await solveAwsChallenge(awsChallengeJS);
    } else if (initialResponse.status === 405) {
        // AWS WAF 验证码 + 挑战
        awsWafCookie = await solveAwsCaptchaChallenge(initialResponse.data, awsChallengeJS);
    } else if (initialResponse.status === 200) {
        console.log("网站加载成功,无需验证码求解。");
        // console.log(initialResponse.data); // 打印最终内容
        return;
    } else {
        console.log(`遇到未处理的状态码: ${initialResponse.status}。`);
        return;
    }

    // 3. 使用获取的 Cookie 再次请求目标页面
    if (awsWafCookie) {
        try {
            console.log("\n--- 第二次请求:使用 AWS WAF Cookie ---");
            console.log(`使用的 Cookie: ${awsWafCookie}`);

            const finalResponse = await axios.get(PAGE_URL, {
                headers: {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                    "Cookie": `aws-waf-token=${awsWafCookie}`
                },
                validateStatus: (status) => status === 200 // 期望最终成功
            });

            console.log(`最终响应状态码: ${finalResponse.status}`);
            console.log("成功获取网站内容!");
            // console.log(finalResponse.data); // 打印最终内容
        } catch (error) {
            console.error(`最终请求失败: ${error.message}`);
        }
    } else {
        console.log("未能获取 AWS WAF Cookie,无法执行第二次请求。");
    }
}

main();

💡 关键点总结

关键点 原始代码问题 优化改进
依赖安装 缺少 cheerio,使用了错误的 Python 语法高亮。 明确说明需要安装 axios 和 cheerio,使用正确的 bash 语法高亮。
任务类型 混合使用 FunCaptchaTaskProxyless 和 AntiAwsWafTask。 统一使用 CapSolver 官方推荐的 AntiAwsWafTask 处理所有 AWS WAF 场景。
参数提取 405 逻辑中提取 awsChallengeJS 的逻辑不完整,202 逻辑中未提取。 在 main 函数中统一提取 awsChallengeJS,并根据状态码调用不同的求解函数(202 或 405)。
错误处理 简单的错误处理,缺乏 API 错误检查和任务等待提示。 在 createTask 和 getTaskResult 中添加 CapSolver API 错误检查(errorId !== 0),并在任务处理期间提供状态提示。
代码结构 所有逻辑集中在 main 函数中,可读性差。 分离为清晰的辅助函数(sleep、createTask、getTaskResult)和核心求解函数(solveAwsChallenge、solveAwsCaptchaChallenge),使逻辑更清晰。
请求头 原始请求头冗余且不完整。 简化并使用更标准的浏览器模拟请求头。

❓ 常见问题(FAQ)

问:为什么需要处理 HTTP 202 和 HTTP 405 状态码?

答: AWS WAF 使用不同的安全措施,导致不同的 HTTP 状态码:

  • HTTP 202(已接受):通常表示需要 WAF 挑战。这是一种较轻量的安全检查,通常涉及运行 JavaScript 代码。
  • HTTP 405(方法不允许):通常表示需要 WAF 验证码,这是一种更复杂的检查,涉及解决视觉或交互式谜题,同时需要挑战参数。我们的脚本设计为能自动检测并处理这两种情况。

问:可以不使用代理使用此脚本吗?

答: 可以。PROXY 变量是可选的。如果您不需要代理,可以在配置中将 const PROXY = "";。然而,对于网页爬取和自动化任务,使用高质量的代理是非常推荐的,以避免 IP 被封禁并确保稳定的访问。

问:什么是 AntiAwsWafTask?

答: AntiAwsWafTask 是 CapSolver 提供的一种专用任务类型,专门用于处理 AWS WAF 安全机制。它智能地处理从受保护页面提取的挑战参数(包括 awsKey、awsIv、awsContext 和 awsChallengeJS),并返回绕过保护所需的 aws-waf-token cookie。

📚 更多信息

  • CapSolver AWS WAF 官方文档: https://docs.capsolver.com/en/guide/captcha/awsWaf/
  • CapSolver API 文档: https://docs.capsolver.com/en/api/

✅ 结论

本指南展示了使用Node.js和**CapSolver**编程解决AWS WAF挑战和验证码的稳健且高效方法。通过实现模块化脚本并利用CapSolver的专业任务类型,您可以将此解决方案无缝集成到自动化工作流中。成功的关键在于正确识别WAF状态码(202或405),提取必要的参数,并将生成的aws-waf-token cookie用于后续请求。这种方法确保您的自动化任务可以可靠地访问受AWS WAF保护的内容。

查看更多

aws wafMar 24, 2026

如何在浏览器自动化中解决Amazon AWS WAF验证码

掌握通过专家策略在浏览器自动化中解决Amazon AWS WAF验证码挑战的技巧。学习如何集成CapSolver以实现无缝高效的自动化工作流程。本指南涵盖基于令牌和基于分类的解决方案。

Anh Tuan
Anh Tuan
aws wafSep 14, 2023

如何使用 PHP 解决 AWS 验证码/挑战:全面指南

一份详细的PHP指南,用于解决AWS WAF CAPTCHA和挑战,以实现可靠的数据抓取和自动化

Emma Foster

目录

Emma Foster
aws wafSep 20, 2023

如何通过 Python 解决 AWS 验证码/挑战

使用Python和CapSolver处理AWS WAF挑战的实用指南,实现更流畅的访问受保护网站

Adélia Cruz
Adélia Cruz
aws wafJul 12, 2023

如何解决 AWS WAF 验证码令牌

本博客解释如何使用 CapSolver 以快速、便宜和简单的方式解决 AWS WAF CAPTCHA

Ethan Collins
Ethan Collins